//
//  main.m
//  OC05_NSArray_NSDictionary_NSSet
//
//  Created by Rain on 16/1/29.
//  Copyright © 2016年 Rain. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "Contact.h"
#import "AddressBook.h"

#pragma mark - 知识点1. NSArray 不可变数组.
void chapter1() {
    
    /** 数组是一个有序集合, 只能存放对象类型. */
    
    /** 不可变数组: 数组创建好之后, 数组内的元素不能发生改变. */
    
#if 0   /** 初始化 */
    
    NSArray *arr = [[NSArray alloc] initWithObjects:@"Tom", @"zhangsan", @"lisi", nil]; /**< 数组中, 是NSString对象. */
    
    
    NSArray *arr2 = [[NSArray alloc] initWithObjects:@2, @20, nil]; /**< 数组中,是NSNumber对象. */
    NSLog(@"arr2:%@", arr2);
    
    NSArray *arr3 = [[NSArray alloc] initWithObjects:arr, arr2, nil];
    NSLog(@"arr3:%@", arr3);
    
    
    NSArray *arr4 = [[NSArray alloc] initWithArray:arr];
    NSLog(@"arr4:%@", arr4);
    
    
    
#endif
    
    
#if 0    /** 便利构造器 */
    
    NSArray *arr = [NSArray arrayWithObjects:@"zhangsan", @"lisi", @"Tom", nil];
    
    
    NSArray *arr2 = [NSArray arrayWithArray:arr];
    
#endif
    
#if 0    /** 字面量 */
    
    NSArray *arr = @[@"zhangsan", @"Lisi", @"Tom"];
    
    NSArray *arr2 = @[arr];
    
    NSArray *arr3 = @[@[@"zhangsan", @"Lisi"],
                      @[@"wangwu", @"Tom"]];
    
    
#endif
    
#if 0    /** 字面量方式获取数组元素 */
    
    NSArray *arr = @[@"zhangsan", @"Tom", @"Lisi"];
    
    NSString *str1 = arr[1];
    
    NSLog(@"str1:%@", str1);
    
#endif
    
#if 0   /** 获取数组元素个数 */
    
    NSArray *arr = @[@"zhangsan", @"lisi", @"Tom"];
    NSLog(@"count:%ld", arr.count);
    
    
#endif
    
    
#if 0    /** 获取数组中指定下标对应的元素 */
    
    NSArray *arr = @[@"zhangsan", @"lisi", @"Tom"];
    
    NSString *str1 = [arr objectAtIndex:1];
    
#endif
    
    
#if 0  /** 用来判断数组中是否包含某一个给定的对象 */
    
    NSArray *arr = @[@"zhangsan", @"lisi", @"Tomo"];
    
    
    if ([arr containsObject:@"Tom"]) {
        
        NSLog(@"含有");
        
    } else {
        
        NSLog(@"不含有");
    }
    
#endif
    
#if 0  /** 获取数组元素对应的索引 */
    
    NSArray *arr = @[@"zhangsan", @"lisi", @"Tom"];
    
    NSInteger index = [arr indexOfObject:@"zhangsan"];
    
    NSLog(@"index:%ld", index);
    
#endif
    
    
#if 0  /** 按照给定的字符串进行截取，将截取的多段字符串放入数组中 */
    /** 练习: 有一个字符串(www.lanou3g.com)，通过.进行分割. */
    
    NSString *str = @"www.lanou3g.com";
    
    NSArray *arr = [str componentsSeparatedByString:@"."];
    
    NSLog(@"arr:%@", arr);
    
    
#endif
    
#if 0 /** 练习: 存在如下的字符串，将其中的图片的网址提取出来。
“http://www.imanhua.com/Cover/2011-10/hyrz.jpg&http://www.imanhua.com/Cover/2011-09/op.jpg&http://www.imanhua.com/Cover/2012-04/yjdwb.jpg */
    
    
    NSString *str = @"http://www.imanhua.com/Cover/2011-10/hyrz.jpg&http://www.imanhua.com/Cover/2011-09/op.jpg&http://www.imanhua.com/Cover/2012-04/yjdwb.jpg";
    
    NSArray *arr = [str componentsSeparatedByString:@"&"];
    NSLog(@"arr:%@", arr);
    
#endif
    
    
#if 0   /** 将数组中的元素按照给定的字符串格式拼接成一个完整的字符串对象 */
    /** 练习: 有一个数组，通过&将所有元素拼接成一个字符串. */
    
    /** 练习: 有如下一个数组，@[@“type = iOS", @"Device = iPhone", @"count = 11344115@163.com", @"password = 12345”]，将其中的内容用”&"符号拼接成一个字符串. */
    
    NSArray *arr = @[@"type = iOS", @"Device = iPhone", @"count = 11344115@163.com", @"password = 12345"];
    
    NSString *para = [arr componentsJoinedByString:@"&"];
    NSLog(@"para:%@", para);
    
    
#endif
    

    
}


#pragma mark - 知识点2. NSMutableArray 可变数组
void chapter2() {

#if 0   /** 初始化 */
    
    NSMutableArray *mArr = [[NSMutableArray alloc] initWithObjects:@"zhangsan", @"Tom", @"lisi", nil];
    
    NSMutableArray *mArr2 = [[NSMutableArray alloc] initWithCapacity:20];
    
    NSMutableArray *mArr3 = [[NSMutableArray alloc] init];
    
    
#endif
    
#if 0    /** 便利构造器 */
    NSMutableArray *mArr = [NSMutableArray array];
    
    NSMutableArray *mArr2 = [NSMutableArray arrayWithCapacity:20];
    
#endif
    
#if 0    /** 字面量 */
    NSMutableArray *mArr = @[@"zhangsan", @"lisi", @"Tom"].mutableCopy;
    
#endif
    
#if 0    /** 数组中添加一个对象 */
    
    NSMutableArray *mArr = [NSMutableArray arrayWithCapacity:20];
    
    [mArr addObject:@"zhangsan"];
    [mArr addObject:@"Lisi"];
    
    NSLog(@"mArr:%@", mArr);
    
    // 获取第一个对象.
    NSString *first = [mArr firstObject];
    
    // 获取最后一个对象.
    NSString *last = [mArr lastObject];
    
    
#endif
    
#if 0   /** 数组中指定位置插入一个对象 */
    
    NSMutableArray *mArr = @[@"zhangsan", @"lisi", @"Tom"].mutableCopy;
    
    
    [mArr insertObject:@"wangwu" atIndex:1];
    
    
    //    NSArray *arr = @[@"zhangsan", @"lisi", mArr];
    
    //    NSMutableArray *m =  [arr objectAtIndex:1];
    
    //    [m insertObject:@"Tom" atIndex:2];
    
#endif
    
#if 0    /** 数组中移除一个对象 */
    
    NSMutableArray *mArr = @[@"zhangsan", @"Tom", @"Lisi", @"Tom"].mutableCopy;
    
    // 删除所有的"Tom"对象.
    [mArr removeObject:@"Tom"];
    
    // 删除指定下标的对象.
    [mArr removeObjectAtIndex:3];
    
    
#endif
    
#if 0    /** 移除数组中最后一个对象 */
    NSMutableArray *mArr = @[@"zhangsan", @"Tom", @"Lisi", @"Tom"].mutableCopy;
    
    [mArr removeLastObject];
    NSLog(@"mArr:%@", mArr);
    
    
    /** 移除数组中所有的元素 */
    //    [mArr removeAllObjects];
    
    /** 数组中移除指定位置的元素 */
    
    /** 使用指定的对象替换指定位置的对象 */
    [mArr replaceObjectAtIndex:0 withObject:@"Leo"];
    
    
    /** 交换指定的两个下标对应的对象 */
    [mArr exchangeObjectAtIndex:1 withObjectAtIndex:2];
    NSLog(@"mArr:%@", mArr);
    
    
#endif
    
#if 0  /**
* 练习: 定义一个数组完成以下操作
(1)向数组中添加三个名字。
(2)从数组中查找指定的名字，并且用另外一个名字替换该姓名。
(3)删除指定的名字。
*/
    
    NSMutableArray *mArr = @[@"zhangsan", @"Tom", @"Lisi", @"Tom"].mutableCopy;
    
    NSInteger index = [mArr indexOfObject:@"zhangsan"];
    
    [mArr replaceObjectAtIndex:index withObject:@"Leo"];
    
    [mArr removeObject:@"Tom"];
    
#endif
}


#pragma mark - 知识点3. NSDictionary 不可变字典
void chapter3() {

/**
 * 字典是一个无序的集合，用来存储具有一一对应关系的数据。
 * 字典中存储的每一个对象都是一对键值对，键值对包含两个部分key和value，key与value的值都是对象类型。
 * 对于每一对key－value称为一个条目(Entry)。
 */
    
#if 0    /** 初始化 */
    
    NSDictionary *dic = [[NSDictionary alloc] initWithObjectsAndKeys:@"name", @"tom", @"age", @20, @"sex", @"male", nil];
    
    NSDictionary *dic2 = [[NSDictionary alloc] initWithObjectsAndKeys:@"tom", @"name", @20, @"age", @"male", @"sex", nil];
    NSLog(@"dic2:%@", dic2);
    
    
#endif
    
#if 0    /** 便利构造器 */
    
    NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys:@"tom", @"name", @"20", @"age", @"male", @"sex", nil];
    
    NSLog(@"dic:%@", dic);
    
#endif
    
#if 0 /** 字面量 */
    
    NSDictionary *dic = @{@"name":@"zhangsan",
                          @"age" :@"20",
                          @"sex" :@"male"
                          };
    NSLog(@"dic:%@", dic);
    
    
    NSDictionary *dic2 = @{@"A":@[
                                   @{@"name":@"axin",
                                     @"age" :@"20",
                                     @"sex" :@"male"},
                                   
                                   @{@"name":@"adai",
                                     @"age" :@"18",
                                     @"sex" :@"male"}
                                   ],
                           
                           @"B":@[
                                   @{@"name":@"baike",
                                     @"age" :@"20",
                                     @"sex" :@"female"},
                                   ],
                           
                           @"Z":@[
                                   @{@"name":@"zhangsan",
                                     @"age" :@"21",
                                     @"sex" :@"male"}
                                   ]
                           };
    NSArray *array = [dic2 objectForKey:@"Z"];
    NSDictionary *dic3 = [array objectAtIndex:0];
    NSString *str = [dic3 objectForKey:@"name"];
    
    
#endif
    
    /** 获取字典中键值对的个数 , API: count. */
    
    /** 获取字典中所有的键, API: allKeys, 返回值是数组. */
    
    /** 获取字典中所有的值, API: allValues, 返回值是数组. */
    
#if 0   /** 根据键获得对应的值, API: objectForKey  */
    
    NSDictionary *dic = @{@"name":@"Tom",
                          @"age" :@"20",
                          @"sex" :@"male"};
    
    NSString *str = [dic objectForKey:@"name"];
#endif
    
}


#pragma mark - 知识点4. NSMutableDictionary 可变字典
void chapter4() {
    
#if 0
    /** 初始化 */
    NSMutableDictionary *mDic = [[NSMutableDictionary alloc] initWithObjectsAndKeys:@"Tom",@"name", @"20", @"age", nil];
    
    NSMutableDictionary *mDic2 = [[NSMutableDictionary alloc] initWithCapacity:20];
    
    
    /** 便利构造器 */
    NSMutableDictionary *mDic3 = [NSMutableDictionary dictionaryWithObjectsAndKeys:@"Tom", @"name", @"20", @"age", nil];
    
    NSMutableDictionary *mDic4 = [NSMutableDictionary dictionary];
    
    /** 字面量 */
    NSMutableDictionary *mDic5 = @{@"name":@"Tom",
                                   @"age" :@"20",
                                   @"sex" :@"male"}.mutableCopy;
    
    
    /** 字典中添加新的键值对或者修改某一键值对值. */
    NSMutableDictionary *mDic = @{@"name":@"Tom",
                                  @"age" :@"20"}.mutableCopy;
    
    [mDic setObject:@"male" forKey:@"sex"];
    NSLog(@"mDic:%@", mDic);
    
    [mDic setObject:@"zhangsan" forKey:@"name"];
    
    /** 移除指定的键对应的键值对 */
    [mDic removeObjectForKey:@"age"];
    NSLog(@"mDic:%@", mDic);
    
    
    /** 移除字典中所有的键值对 */
    [mDic removeAllObjects];
    NSLog(@"mDic:%@", mDic);
#endif
    
}


#pragma mark - 知识点5. NSSet 不可变集合
void chapter5() {
    
    /**
     * 互异性(唯一性)  集合中不能够存在两个相同的对象。
     * 无序性  集合中的对象没有顺序，先添加的对象不一定在集合中的第一个位置，后添加的也不一定在最后的位置。
     * 多用于重用池, 执行效率比数组高, 且可以避免重复元素
     
     */
    
#if 0   /** 初始化 */
    NSSet *set = [[NSSet alloc] initWithObjects:@"zhangsan", @"Tom", @"lisi", nil];
    NSLog(@"set:%@", set);
    
    
#endif
    /** 便利构造器 */
    NSSet *set = [NSSet setWithObjects:@"zhangsan", @"lisi", @"Tom", @"Tom", nil];
    NSLog(@"set:%@", set);
    

    /** 获取集合中对象的个数 */
    NSLog(@"count:%ld", set.count);
    
  
    /** 获取集合中所有的对象 */
    NSArray *arr = [set allObjects];
    
    /** 从集合中取出一个对象 */
    NSString *anyString = [set anyObject];
    
    
    /** 判断集合中是否包含某一个指定的对象 */
    BOOL isCon = [set containsObject:@"zhangsan"];
    
    /** 没有字面量 */
    BOOL iscon2 = [set containsObject:@"Tom"];
    
}


#pragma mark - 知识点6. NSMutableSet 可变集合
void chapter6() {
    
    /** 初始化 */
    NSMutableSet *mSet = [[NSMutableSet alloc] initWithObjects:@"zhangsan", @"lisi", @"Tom", nil];
    

    /** 便利构造器 */
    
    NSArray *arr = @[@"zhangsan", @"Tom", @"Tom", @"lisi"];
    
    NSMutableSet *mSet2 = [NSMutableSet setWithArray:arr];
    
    NSMutableSet *mSet3 = [NSMutableSet setWithObject:arr];
    
    NSLog(@"mSet2:%@", mSet2);
    
    /** 添加一个对象 */
    [mSet2 addObject:@"zhangsan"];
    NSLog(@"mSet2:%@", mSet2);
    
    /** 移除一个对象 */
    [mSet2 removeObject:@"zhangsan"];
    
    /** 移除所有对象 */
    [mSet2 removeAllObjects];
}

#pragma mark - 知识点7. NSCountedSet 计数集合.
void chapter7() {
    
    // 创建对象.
    NSArray *arr = @[@"zhangsan", @"zhangsan", @"Lisi", @"mi", @"Lisi", @"zhangsan"];
    
    NSCountedSet *set = [[NSCountedSet alloc] initWithArray:arr];
    
    NSLog(@"set:%@", set);
    
    // 核心API, 获取对象出现的次数.
    NSUInteger count = [set countForObject:@"zhangsan"];
    
    NSLog(@"count:%ld", count);
    
}


#pragma mark - 练习: 通讯录
void exercise1() {
    
    /**
     * 练习: 完成以下需求:
     以封装方式完成:
     1、定义联系人类Contact。实例变量：姓名(拼音，首字母大写)、性别、电话号码、住址、分组名称、年龄.
     方法: (1),自定义初始化方法(姓名、电话号码)、显示联系人信息。
     
     2. 定义一个通讯录类(AddBook), 实例变量:容器(用来存放联系人, 分组管理所有联系人。分组名为26个大写的英文字母)
     
     方法：
     (1).可以添加联系人对象，如果姓名或电话号码为空，添加失败。添加联系人到匹配的分组。
     
     (2). 删除某个分组的全部联系人。
     */
    
    // 创建通讯录对象.
    AddressBook *ab = [[AddressBook alloc] init];
    
    // 创建联系人对象.
    Contact *con1 = [Contact contactWithName:@"zhangsan" phoneNumber:@"13198772083"];
    
    Contact *con2 = [Contact contactWithName:@"Lisi" phoneNumber:@"13098724322"];
    
    // 通讯录调用方法,实现功能
    [ab addContact:con1];
    [ab addContact:con2];
    
    
    
    
}


#pragma mark - main 函数
int main(int argc, const char * argv[]) {
    
//    chapter1();
    
//    chapter2();
    
//    chapter3();
    
//    chapter4();
    
//    chapter5();
    
//    chapter6();
    
//    exercise1();

    chapter7();
    
    return 0;
}
